/*
 * @author Rizky Abdilah <rizky@abdi.la>
 * @date Agustus 2014
 * @last 14 Agustus 2014 / ?_=2
 * 
 * Library untuk embed player live streaming.
 * List flash player yang di support:
 *  - JWPlayer
 *  - VideoJS
 *  - GrindPlayer (OSMF)
 *  - Chromeless
 *
 * Jika browser tidak support flash maka akan ditampilkan link untuk memutar
 * videonya (iphone dan ipad hls m3u8, android rtsp), pengecekan user agent
 * dilakukan melalui API Live Streaming.
 *
 */

var DGSTREAM = (function(){
    function S(streamHost, streamName){
        this.streamHost = streamHost;
        this.streamApi = this.streamUrl("/info/" + streamName);
        this.streamInfo = {};
        this.opt = {
            player: "player",
            width: 640,
            height: 360,
            autoplay: false,
            forcePlayer: null,
            debug: false,
        };
    }
    
    S.prototype.render = function(){
        dgself = this;
        var callback = dgself.genRandomCallback();
        window[callback] = function(data){
            dgself.callbackApi(data);
        };
        dgself.appendJs(dgself.streamApi + "?callback=" + callback)
    };
    
    S.prototype.callbackApi = function(data){
        this.streamInfo = data.result;
        if (data.status != 1) {
            alert(data.result.error_message);
            return;
        }
        
        // todo build debug statistic
        var checkRecom = this.streamInfo.recommended_usage;
        if (this.opt.forcePlayer != null) {
            checkRecom = this.opt.forcePlayer;
        }
        switch (checkRecom){
            case "android":
                this.buildRtsp(); break;
            case "ios_hls":
                this.buildHls(); break;
            case "hls":
                this.buildJWPlayer(["hls"]); break;
            case "osmf":
                this.buildFlashHls(); break;
            case "chromeless":
                this.buildHlsChromeless(); break;
            case "smil":
            case "jwplayer":
                this.buildJWPlayer(["smil", "hls"]); break;
            case "rtmp":
            case "videojs":
                this.buildVideoJS(); break;
            default:
                this.buildJWPlayer();
        }
    };
    
    S.prototype.setOpt = function(opts){
        for (optKey in opts) {
            this.opt[optKey] = opts[optKey];
        }
    };
    
    S.prototype.streamUrl = function(relPath){
        return this.streamHost + relPath;
    };
    
    S.prototype.appendJs = function(url){
        var jp = document.createElement('script'); jp.type = 'text/javascript';
        jp.src = url;
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(jp, s);
    };
    
    S.prototype.appendCss = function(url){
        var jp = document.createElement('link'); jp.rel = 'stylesheet';
        jp.href = url; jp.type = 'type/css';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(jp, s);
    };
    
    S.prototype.genRandomCallback = function(){
        return "callback_" + (Math.random() * 100).toString().replace(".", "");
    };
    
    // support both rtmp and m3u8, but not yet support adaptive streaming
    S.prototype.buildVideoJS = function(){
        dgself = this;
        yepnope({
            load: [dgself.streamUrl("/vjs/video.js"), dgself.streamUrl("/vjs/videojs-media-sources.js"),
                dgself.streamUrl("/vjs/videojs.hls.min.js"), dgself.streamUrl("/vjs/video-js.css")],
            complete: function(){
                videojs.options.flash.swf = dgself.streamUrl("/vjs/video-js.swf");
                var link = '<video id="dgstream-player" class="video-js vjs-default-skin vjs-live"\
                controls preload="auto"  width="'+dgself.opt.width+'" height="'+dgself.opt.height+'" autoplay>"\
                <source src="'+dgself.streamInfo.rtmp[0].url+'" type="rtmp/mp4" /></video>';
                document.getElementById(dgself.opt.player).innerHTML = link;
                videojs("dgstream-player", {}, function(){});
            },
        });
    };
    
    // for browser support flash, and prefer using rtmp instead m3u8
    S.prototype.buildJWPlayer = function(sources){
        dgself = this;
        yepnope.injectJs(this.streamUrl("/jwplayer/jwplayer.premium.js"), function(){
            jwplayer.key = '/Ud4VPhWXhRKnqxedjUsamwuepQhAgd5x8/GNTIMENQ=';
            var jwplayerSources = [];
            for (var i = 0; i < sources.length; i++) {
                jwplayerSources.push({file: dgself.streamInfo[sources[i]]});
            }
            jwplayer(dgself.opt.player).setup({
                'autostart': dgself.opt.autoplay,
                'flashplayer': dgself.streamUrl('/jwplayer/jwplayer.premium.swf'),
                'html5player': dgself.streamUrl('/jwplayer/jwplayer.html5.js'),
                'width': dgself.opt.width,
                'height': dgself.opt.height,
                'stretching': 'uniform',
                'sharing': {},
                'aspectratio': '16:9',
                'sources': jwplayerSources,
                'skin': dgself.streamUrl('/jwplayer/stormtrooper.xml'),
            });

        });
    };
    
    // for native android browser, via apps using m3u8 (hls)
    S.prototype.buildRtsp = function(){
        var link = '<a href="'+this.streamInfo.android+'">\
        <img src="'+this.streamInfo.thumbnail+'" width="'+this.opt.width+'" /></a>';
        document.getElementById(this.opt.player).innerHTML = link;
    };
    
    // for native m3u8 iphone, ipad
    S.prototype.buildHls = function(){
        var link = '<a href="'+this.streamInfo.ios_hls+'">\
        <img src="'+this.streamInfo.thumbnail+'" width="'+this.opt.width+'" /></a>';
        document.getElementById(this.opt.player).innerHTML = link;
    };
    
    S.prototype.flashHlsBridge = function(playerId, event, data){
        if (this.player == null){
            this.player = document.getElementById(playerId);
        }
        switch(event){
            case "onJavaScriptBridgeCreated":
            case "timeChange":
            case "timeupdate":
            case "progress":
            default:
                if (this.debug) {
                    console.log(event, data);
                }
                break;
        }
    };
    
    // for browser support flash
    S.prototype.buildFlashHls = function(){
        dgself = this;
        parameters = {
            src: dgself.streamInfo.hls,
            autoPlay: dgself.opt.autoplay.toString(),
            verbose: true,
            controlBarAutoHide: "true",
            controlBarPosition: "bottom",
            poster: dgself.streamInfo.thumbnail,
            javascriptCallbackFunction: "flashHlsBridge",
            plugin_hls: dgself.streamUrl("/flashls/flashlsOSMF.swf"),
            hls_minbufferlength: -1,
            hls_maxbufferlength: 30,
            hls_lowbufferlength: 3,
            hls_seekmode: "SEGMENT_SEEK",
            hls_startfromlevel: -1,
            hls_seekfromlevel: -1,
            hls_live_flushurlcache: false,
            hls_info: true,
            hls_debug: false,
            hls_debug2: false,
            hls_warn: true,
            hls_error: true,
            hls_fragmentloadmaxretry : -1,
            hls_manifestloadmaxretry : -1,
            hls_capleveltostage : false,
            hls_maxlevelcappingmode : "downscale"
        };
        if (dgself.opt.debug) {
            parameters['hls_debug'] = true;
            parameters['hls_debug2'] = true;
        }
        yepnope.injectJs(dgself.streamUrl("/flashls/swfobject.js"), function(){
            swfobject.embedSWF(
                dgself.streamUrl('/flashls/GrindPlayer.swf'),
                dgself.opt.player,
                dgself.opt.width,
                dgself.opt.height,
                "10.1.0",
                "expressInstall.swf",
                parameters,
                {allowFullScreen: "true", wmode: "direct", allowScriptAccess: 'always'},
                {name: dgself.opt.player}
            );
        });
    };
    
    S.prototype.chromelessAutoplay = function(){
        dgself = this;
        var player = document.getElementById(dgself.opt.player);
        if (player && typeof player.playerLoad === "function") {
            player.playerLoad(dgself.streamInfo.hls);
            player.playerPlay();
            window.clearTimeout(window._timeoutId);
        } else{
            window._timeoutId = window.setTimeout(function(){
                dgself.chromelessAutoplay();
            }, 200);
        }
    };
    
    S.prototype.buildHlsChromeless = function(){
        dgself = this;
        yepnope.injectJs(dgself.streamUrl("/flashls/swfobject.js"), function(){
            swfobject.embedSWF(
                dgself.streamUrl('/chromeless/flashlsChromeless.swf'),
                dgself.opt.player,
                dgself.opt.width,
                dgself.opt.height,
                "10.1.0",
                "expressInstall.swf",
                {},
                {allowFullScreen: "true", wmode: "direct", allowScriptAccess: 'always'},
                {name: dgself.opt.player},
                function(e) {
                    window._timeoutId = window.setTimeout(function(){
                        dgself.chromelessAutoplay();
                    }, 200);
                }
            );
        });
    };
    
    return S;
})();

// end of file

